<script setup lang="ts">
import { VisXYContainer, VisLine, VisAxis, VisArea } from '@unovis/vue';

interface MetricData {
  code: number;
  msg: string;
  data: {
    cpu_total: number;
    cpu_used: number;
    memory_total: number;
    memory_used: number;
    gpu_total: number;
    gpu_used: number;
    storage_total: number;
    storage_used: number;
  };
}

interface UsageData {
  time: number;
  usage: number;
}

const seedgen = () => new Date().getHours();
const rand = sfc32(seedgen(), seedgen(), seedgen(), seedgen());

const useMetric = async () => {
  // const url = '/api/v1/cluster/metrics';
  // const { data } = await useFetch<MetricData>(url);
  const data = ref({
    code: 200,
    msg: '',
    data: {
      cpu_total: 10,
      cpu_used: 0.34,
      memory_total: 39340.023,
      memory_used: 4367.5664,
      gpu_total: 1,
      gpu_used: 0,
      storage_total: 120418.9,
      storage_used: 92876
    }
  });
  return { data };
};

const genFakeMetricData = (
  initData: number,
  range: [number, number],
  limit: [number, number],
  step: number,
  randomGenerator: () => number
) => {
  const [start, end] = range;
  const [min, max] = limit;
  const data = [
    {
      time: end,
      usage: initData
    }
  ];
  for (let i = end - step; i >= start; i -= step) {
    const r = randomGenerator();
    initData = Math.min(Math.max(initData + r, min), max);
    data.push({
      time: i,
      usage: initData
    });
  }
  return { data };
};

const generateFullMetricData = (initData: MetricData) => {
  const {
    cpu_total,
    cpu_used,
    memory_total,
    memory_used,
    storage_used,
    storage_total,
    gpu_used,
    gpu_total
  } = initData.data;
  const end = Date.now() / 1000;
  const start = end - 60 * 60 * 24;

  const { data: cpuData } = genFakeMetricData(
    (cpu_used / cpu_total) * 100,
    [start, end],
    [5, 100],
    900,
    () => rand() * 3 - 1.5
  );
  const { data: memoryData } = genFakeMetricData(
    (memory_used / memory_total) * 100,
    [start, end],
    [5, 100],
    900,
    () => rand() * 4 - 2
  );
  const { data: storageData } = genFakeMetricData(
    (storage_used / storage_total) * 100,
    [start, end],
    [5, 100],
    900,
    () => rand() * 4 - 2
  );
  const { data: gpuData } = genFakeMetricData(
    (gpu_used / gpu_total) * 100,
    [start, end],
    [5, 100],
    900,
    () => 0
  );
  cpuData.reverse();
  memoryData.reverse();
  storageData.reverse();
  gpuData.reverse();
  return { start, end, cpuData, memoryData, storageData, gpuData };
};

const { data: initMetricData } = await useMetric();
const { cpuData, memoryData, storageData, gpuData } = generateFullMetricData(
  initMetricData.value
);
const x = (data: UsageData) => +new Date(data.time * 1000);
const y = [(data: UsageData) => data.usage];
const opacity = ref(0.5);
</script>

<template>
  <div>
    <v-row>
      <v-col cols="3">
        <v-card>
          <div class="p-6 overflow-hidden relative">
            <div class="text-h5">云计算集群数目</div>
            <div class="text-h1 text-primary pt-5">1</div>
            <div class="absolute -bottom-10 -right-6 opacity-65">
              <v-icon icon="mdi-cloud" color="primary" size="200" />
            </div>
          </div>
        </v-card>
      </v-col>

      <v-col cols="3">
        <v-card>
          <div class="p-6 overflow-hidden relative">
            <div class="text-h5">边计算集群数目</div>
            <div class="text-h1 text-cyan pt-5">2</div>
            <div class="absolute -bottom-12 -right-8 opacity-65">
              <v-icon icon="mdi-server" color="cyan" size="200" />
            </div>
          </div>
        </v-card>
      </v-col>

      <v-col cols="3">
        <v-card>
          <div class="p-6 overflow-hidden relative">
            <div class="text-h5">端设备数目</div>
            <div class="text-h1 text-teal pt-5">6</div>
            <div class="absolute -bottom-8 -right-4 opacity-65">
              <v-icon icon="mdi-devices" color="teal" size="200" />
            </div>
          </div>
        </v-card>
      </v-col>

      <v-col cols="3">
        <v-card>
          <div class="p-6 overflow-hidden relative">
            <div class="text-h5">总设备数目</div>
            <div class="text-h1 text-indigo pt-5">20</div>
            <div class="absolute -bottom-8 -right-8 opacity-65">
              <v-icon icon="mdi-cog" color="indigo" size="200" />
            </div>
          </div>
        </v-card>
      </v-col>
    </v-row>

    <v-row>
      <v-col cols="6">
        <v-card>
          <v-card-title class="text-h5 ml-2" justify="center">
            CPU使用量
          </v-card-title>
          <v-card-text class="m-2">
            <VisXYContainer :height="200" :y-domain="[0, 100]">
              <VisLine :data="cpuData" :x="x" :y="y" />
              <VisAxis
                type="x"
                :tick-format="
                  (value: Date) => new Date(value).toLocaleTimeString()
                "
              />
              <VisAxis type="y" :tick-format="(value: number) => value + '%'" />
            </VisXYContainer>
          </v-card-text>
        </v-card>
      </v-col>

      <v-col cols="6">
        <v-card>
          <v-card-title class="text-h5 ml-2" justify="center">
            GPU使用量
          </v-card-title>
          <v-card-text class="m-2">
            <VisXYContainer :height="200" :y-domain="[0, 100]">
              <VisArea
                color="red"
                :opacity="opacity"
                :data="gpuData"
                :x="x"
                :y="y"
              />
              <VisAxis
                type="x"
                :tick-format="
                  (value: Date) => new Date(value).toLocaleTimeString()
                "
              />
              <VisAxis type="y" :tick-format="(value: number) => value + '%'" />
            </VisXYContainer>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>

    <v-row>
      <v-col cols="6">
        <v-card>
          <v-card-title class="text-h5 ml-2" justify="center">
            存储空间使用量
          </v-card-title>
          <v-card-text class="m-2">
            <VisXYContainer :height="200" :y-domain="[0, 100]">
              <VisLine :data="storageData" :x="x" :y="y" color="blue" />
              <VisAxis
                type="x"
                :tick-format="
                  (value: Date) => new Date(value).toLocaleTimeString()
                "
              />
              <VisAxis type="y" :tick-format="(value: number) => value + '%'" />
            </VisXYContainer>
          </v-card-text>
        </v-card>
      </v-col>

      <v-col cols="6">
        <v-card>
          <v-card-title class="text-h5 ml-2" justify="center">
            内存使用量
          </v-card-title>
          <v-card-text class="m-2">
            <VisXYContainer :height="200" :y-domain="[0, 100]">
              <VisArea
                color="orange"
                :opacity="opacity"
                :data="memoryData"
                :x="x"
                :y="y"
              />
              <VisAxis
                type="x"
                :tick-format="
                  (value: Date) => new Date(value).toLocaleTimeString()
                "
              />
              <VisAxis type="y" :tick-format="(value: number) => value + '%'" />
            </VisXYContainer>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>
  </div>
</template>
